object Rationals
{
    def main() : Unit = { println(new RationalsTester().Test()); }
}

class RationalsTester
{
   
    def Test() : String =
    {
        var oR1 : Rational;
        var oR2 : Rational;
        var oR3 : Rational;
        var szRes : String;
        oR1 = new Rational().New(0, 75);
        oR2 = new Rational().New(56, 1024);
        oR3 = new Rational().New(1, 1);
        szRes = "Addition : " + oR3.Add(oR1, oR2).ToString() + " | "
                + "Substraction : " + oR3.Substract(oR1, oR2).ToString() + " | "
                + "Multiplication : " + oR3.Multiply(oR1, oR2).ToString() + " | "
                + "Division : " + oR3.Divide(oR1, oR2).ToString();
        return szRes;
    }
   
}


class Rational
{
    var nNum : Int;
    var nDenom : Int;
   
    def GetNum() : Int = { return nNum; }
    def GetDenum() : Int = { return nDenom; }
   
   
    def New(num : Int, denom : Int) : Rational =
    {
        if(denom == 0) { println("Denominator cannot be 0."); nNum = 0; }
        else
        {
            nNum = num;
            nDenom = denom;
        }
        return this;
    }
   
   
    def IsNull() : Bool = { return (nNum == 0); }
   
   
    def Opposite() : Rational =
    {
        var nMinusOne : Int; nMinusOne = 0 - 1;
        return new Rational().New(nNum * nMinusOne, nDenom);
    }
   
   
    def Inverse() : Rational = { return new Rational().New(nDenom, nNum); }
   
   
    def Simplify() : Rational =
    {
        while(!this.IsNull() && this.CanBeSimplified())
        {
            nNum = nNum / 2;
            nDenom = nDenom / 2;
        }
        return this;
    }
   
   
    def CanBeSimplified() : Bool =
    {
        var bOk : Bool; var nNumTemp : Int; var nDenomTemp : Int;
        nNumTemp = nNum / 2;
        nDenomTemp = nDenom / 2;
        if(nNumTemp * 2 == nNum && nDenomTemp * 2 == nDenom) { bOk = true; }
        else { bOk = false; }
        return bOk;
    }
   
   
    def CommonDenomerator(oRational1 : Rational, oRational2 : Rational) : Int[]  =
    {
        var nResArray : Int[]; var nCommonDenom : Int; var nNum1 : Int; var nNum2 : Int; var nDenom1 : Int; var nDenom2 : Int;
        nNum1 = oRational1.GetNum(); nNum2 = oRational2.GetNum(); nDenom1 = oRational1.GetDenum(); nDenom2 = oRational2.GetDenum();
       
        if(nDenom1 == nDenom2) { nCommonDenom = nDenom1; }
        else
        {
            nCommonDenom = nDenom1 * nDenom2;
            nNum1 = nNum1 * nDenom2;
            nNum2 = nNum2 * nDenom1;
        }
        nResArray = new Int[3];
        nResArray[0] = nCommonDenom;
        nResArray[1] = nNum1;
        nResArray[2] = nNum2;
        return nResArray;
    }
   
   
    def Add(oRational1 : Rational, oRational2 : Rational) : Rational =
    {
        var nArray : Int[];
        nArray = this.CommonDenomerator(oRational1, oRational2);
        nNum = nArray[1] + nArray[2];
        nDenom = nArray[0];
        return this.Simplify();
    }
   
   
    def Substract(oRational1 : Rational, oRational2 : Rational) : Rational =
    { return this.Add(oRational1, oRational2.Opposite()); }
   
   
    def Multiply(oRational1 : Rational, oRational2 : Rational) : Rational =
    {
        nNum = oRational1.GetNum() * oRational2.GetNum();
        nDenom = oRational1.GetDenum() * oRational2.GetDenum();
        return this.Simplify();
    }
   
   
    def Divide (oRational1 : Rational, oRational2 : Rational) : Rational =
    {
        var oRet : Rational;
        if(oRational2.IsNull()) { println("Error : division by zero."); oRet = oRational2; }
        else { oRet = this.Multiply(oRational1, oRational2.Inverse()); }
        return oRet;
    }
   
   
    def ToString() : String =
    {
        var szRes : String;
        szRes = "(" + nNum + "/" + nDenom + ")";
        return szRes;
    }

}